package me.hunche.app.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import me.hunche.app.dao.ActivityDao;
import me.hunche.app.dao.CarDao;
import me.hunche.app.dao.TeamDao;
import me.hunche.app.dao.UserDao;
import me.hunche.app.domain.Activity;
import me.hunche.app.domain.ActivityMember;
import me.hunche.app.domain.Team;
import me.hunche.app.domain.User;
import me.hunche.app.exception.UserJoinedException;
import me.hunche.app.service.ActivityMemberService;
import me.hunche.app.service.ActivityService;
import me.hunche.app.service.CoreService;
import me.hunche.app.service.NotifyService;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.feinno.framework.common.exception.BusinessException;
import com.hp.hpl.helper.misc.DateHelper;

@Service("coreService")
public class CoreServiceImpl implements CoreService {
	
	private static final Logger logger = Logger.getLogger(CoreServiceImpl.class);
	
	@Autowired ActivityDao activityDao;
	@Autowired ActivityService activityService;
	@Autowired TeamDao teamDao;
//	@Autowired ActivityMemberDao activityMemberDao;
	@Autowired ActivityMemberService activityMemberService;
	@Autowired UserDao userDao;
	@Autowired CarDao carDao;
	
	@Autowired NotifyService  notifyService;

	public Long createTeam(Team team) {
		team.setCreateTime(new Date(System.currentTimeMillis()));
		teamDao.save(team);
		return team.getId();
	}

	public Long createUser(User user) {
		user.setCreateTime(new Date(System.currentTimeMillis()));
		userDao.save(user);
		
		if(user.getCar()!=null){
			user.getCar().setOwnerId(user.getId());
			carDao.save(user.getCar());
		}
		
		return user.getId();
	}

	public void crateActivity(Activity a) {
		a.setActivityDate(DateHelper.dayStart(a.getActivityDate()));
		a.setStatus(Activity.STATUS_NEW);
		a.setCreateDate(DateHelper.now());
		activityDao.save(a);
//		notifyService.created(a);
	}
	
	
	public void recruit(Activity a) {
//		if(Activity.STATUS_RECRUIT != a.getStatus()){
			a.setStatus(Activity.STATUS_RECRUIT);
			activityDao.update(a);
			notifyService.recruit(a);
//		}
	}
	
	public void recruit(Long activityId, String userIds) {
		Activity a = activityService.findActivityById(activityId);
		a.setStatus(Activity.STATUS_RECRUIT);
		
		String[] array = userIds.split(",");
		
		List<Long> ids = new ArrayList();
		for(String id:array){
			ids.add(Long.valueOf(id));
		}
		
		List<User> rs = userDao.findByIdIn(ids);
		activityDao.update(a);
		notifyService.recruit2(a, rs);
	}

	
	//TODO 优化
	@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
	public Activity joinActivity(List<User> users, Long activityId, Boolean notification) {
		Activity a = activityService.findActivityById(activityId);
		
		for(User u:users){
			joinActivity(u,a,notification);
		}
		
		return a;
	}

	public Activity joinActivity(String mobile, Long activityId, Boolean needNotify) {
		User user = userDao.findByMobile(mobile);
		return joinActivity(user,activityId,needNotify);
	}
	
	public Activity joinActivity(User user, Long activityId, Boolean needNotify) {
		Activity a = activityService.findActivityById(activityId);
		return joinActivity(user,a,needNotify);
	}
	
	public Activity joinActivity(User user, Activity a, Boolean needNotify) {
//		Activity a = activityService.findActivityById(activityId);
		if(Activity.STATUS_OVER == a.getStatus() || Activity.STATUS_CANCELED == a.getStatus() ){
			throw new BusinessException("活动已结束");
		}
		
		if(Activity.STATUS_CANCELED == a.getStatus() ){
			throw new BusinessException("活动已取消");
		}
		
		if(!a.getTeamId().equals(user.getTeamId())){
			throw new BusinessException("用户不是车队队员");
		}
		
		List<ActivityMember> allMembers = a.getAllMembers();
		if(allMembers==null){
			allMembers = new ArrayList<ActivityMember>();
			a.setAllMembers(allMembers);
		}else{
			for(ActivityMember t:allMembers){
				if(t.getUserId().equals(user.getId())){
					throw new UserJoinedException();
				}
			}
		}
		
		boolean notEnough =  allMembers.size() < a.getAmount();
		boolean isRecruiting = Activity.STATUS_RECRUIT == a.getStatus();
		
		ActivityMember am = new ActivityMember();
		am.setActivityId(a.getId());
		am.setUserId(user.getId());
		am.setMobile(user.getMobile());
		am.setNickname(user.getNickname());
		am.setJoinTime(new Date(System.currentTimeMillis()));
		if(!isRecruiting && notEnough){
			am.setType(ActivityMember.TYPE_REGULAR);
		}else{
			am.setType(ActivityMember.TYPE_RESERVE);
		}
		
		activityMemberService.save(am);
		
		allMembers.add(am);
		
		if(needNotify){
			if(isRecruiting){
				notifyService.result(a,user);
			}else{
				notifyService.confirmed(a, am);
			}
		}
		return a;
	}

	public void startActivity(Long activityId, Long leaderId, Long[] memberIds) {
		Activity a = activityDao.get(activityId);
		List<ActivityMember> ms = activityMemberService.findByActivityId(activityId);
		for(ActivityMember m:ms){
			if(m.getId().equals(leaderId)){
				m.setType(ActivityMember.TYPE_LEADER);
				activityMemberService.save(m);
				break;
			}
		}
		
		for(Long mid:memberIds){
			for(ActivityMember m:ms){
				if(m.getId().equals(mid)){
					m.setType(ActivityMember.TYPE_REGULAR);
					activityMemberService.save(m);
				}
			}
		}
		notifyService.confirmed(a);
	}

	public void cancleActivity(Long activityId) {
		Activity a = activityDao.get(activityId);
		notifyService.canceled(a);
	}

	@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
	public void confirmActivity(Long activityId, Long leaderId, Long[] memberIds) {
		Activity a = activityDao.get(activityId);
		if(Activity.STATUS_RECRUIT != a.getStatus()){
			throw new BusinessException("活动不在召集期");
		}
		
		List<ActivityMember> ms = activityMemberService.findByActivityId(activityId);
		for(ActivityMember m:ms){
			if(m.getId().equals(leaderId)){
				m.setType(ActivityMember.TYPE_LEADER);
				activityMemberService.save(m);
				a.setLeader(m);
				break;
			}
		}
		
		List<ActivityMember> members = new ArrayList<ActivityMember>();
		for(Long mid:memberIds){
			for(ActivityMember m:ms){
				if(m.getId().equals(mid)){
					m.setType(ActivityMember.TYPE_REGULAR);
					activityMemberService.save(m);
					members.add(m);
				}
			}
		}
		
		List<ActivityMember> reserveMembers = new ArrayList();
		for(ActivityMember m:ms){
			if(ActivityMember.TYPE_RESERVE == m.getType()){
				reserveMembers.add(m);
			}
		}

		a.setReserveMembers(reserveMembers);
		a.setMembers(members);
		a.setAllMembers(ms);
		
		a.setStatus(a.STATUS_PREP);
		activityDao.save(a);
		try {
			notifyService.confirmed(a);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("notifyService.confirmed faild!msg->"+e.getMessage());
		}
	}

	public void ready(Activity a) {
		a.setStatus(Activity.STATUS_READY2);
		activityService.update(a);
		notifyService.ready(a);
	}

	public void go(Activity a) {
		a.setStatus(Activity.STATUS_GOING);
		activityService.update(a);
		notifyService.go(a);
	}





}
